package edu.sdjzu.exam.service.impl;

import edu.sdjzu.exam.mapper.*;
import edu.sdjzu.exam.domain.*;
import edu.sdjzu.exam.domain.auth.*;
import edu.sdjzu.exam.service.rbac.RbacService;
import edu.sdjzu.exam.common.CommonResponse;
import edu.sdjzu.exam.enums.AuthResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class RbacServiceImpl implements RbacService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    @Autowired
    private ActivityLogMapper activityLogMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;

    // 用户操作
    @Override
    public List<User> getAllUsers() {
        return userMapper.findAll();
    }

    @Override
    public User createUser(User user) {
        user.setPassword(user.getPassword());
        userMapper.insert(user);
        logActivity(user.getUserId(), "create_user", null, "用户创建: " + user.getUsername());
        return user;
    }

    @Override
    public User findUserById(Long userId) {
        return userMapper.findById(userId);
    }

    @Override
    public User findUserByUsername(String username) {
        return userMapper.findByUsername(username);
    }
    
    @Override
    public User findUserByEmail(String email) {
        return userMapper.findByEmail(email);
    }

    @Override
    public void updateUser(User user) {
        userMapper.update(user);
        logActivity(user.getUserId(), "update_user", null, "用户更新: " + user.getUsername());
    }

    @Override
    public void deleteUser(Long userId) {
        userMapper.delete(userId);
        logActivity(userId, "delete_user", null, "用户删除");
    }

    // 角色操作
    @Override
    public List<Role> getAllRoles() {
        return roleMapper.findAll();
    }

    @Override
    public Role createRole(Role role) {
        roleMapper.insert(role);
        logActivity(null, "create_role", null, "角色创建: " + role.getRoleName());
        return role;
    }

    @Override
    public Role findRoleById(Long roleId) {
        return roleMapper.findById(roleId);
    }

    @Override
    public Role findRoleByName(String roleName) {
        return roleMapper.findByName(roleName);
    }

    @Override
    public void updateRole(Role role) {
        roleMapper.update(role);
        logActivity(null, "update_role", null, "角色更新: " + role.getRoleName());
    }

    @Override
    public void deleteRole(Long roleId) {
        roleMapper.delete(roleId);
        logActivity(null, "delete_role", null, "角色删除: roleId=" + roleId);
    }

    // 权限操作
    @Override
    public List<Permission> getAllPermissions() {
        return permissionMapper.findAll();
    }

    @Override
    public Permission createPermission(Permission permission) {
        permissionMapper.insert(permission);
        logActivity(null, "create_permission", null, "权限创建: " + permission.getPermissionName());
        return permission;
    }

    @Override
    public Permission findPermissionById(Long permissionId) {
        return permissionMapper.findById(permissionId);
    }

    @Override
    public Permission findPermissionByName(String permissionName) {
        return permissionMapper.findByName(permissionName);
    }

    @Override
    public void updatePermission(Permission permission) {
        permissionMapper.update(permission);
        logActivity(null, "update_permission", null, "权限更新: " + permission.getPermissionName());
    }

    @Override
    public void deletePermission(Long permissionId) {
        permissionMapper.delete(permissionId);
        logActivity(null, "delete_permission", null, "权限删除: permissionId=" + permissionId);
    }

    // 用户-角色分配
    @Override
    @Transactional
    public void assignRoleToUser(Long userId, Long roleId) {
        UserRole userRole = new UserRole();
        userRole.setUserId(userId);
        userRole.setRoleId(roleId);
        userRoleMapper.insert(userRole);
        logActivity(userId, "assign_role", null, "分配角色: roleId=" + roleId);
    }

    @Override
    @Transactional
    public void removeRoleFromUser(Long userId, Long roleId) {
        userRoleMapper.delete(userId, roleId);
        logActivity(userId, "remove_role", null, "移除角色: roleId=" + roleId);
    }

    @Override
    public List<Role> getUserRoles(Long userId) {
        return userRoleMapper.findRolesByUserId(userId);
    }

    @Override
    public List<Role> findRolesByUserId(Long userId) {
        return userRoleMapper.findRolesByUserId(userId);
    }
    
    // 超级管理员创建老师用户
    @Override
    @Transactional
    public CommonResponse<String> createTeacherUser(String username, String password, String email, String realname, Long adminId) {
        try {
            // 1. 检查用户是否存在
            User existingUser = findUserByUsername(username);
            if (existingUser != null) {
                return CommonResponse.fail(AuthResultCode.USER_EXISTS.code, AuthResultCode.USER_EXISTS.message);
            }
            
            // 2. 创建用户
            User user = new User();
            user.setUsername(username);
            String encodedPassword = passwordEncoder.encode(password);
            user.setPassword(encodedPassword);
            user.setEmail(email);
            user.setRealname(realname);
            
            createUser(user);
            
            // 3. 验证用户创建
            User createdUser = findUserByUsername(username);
            if (createdUser == null || createdUser.getUserId() == null) {
                throw new RuntimeException("用户创建失败");
            }
            
            // 4. 分配老师角色
            Role teacherRole = findRoleByName("teacher");
            if (teacherRole == null) {
                throw new RuntimeException("老师角色不存在");
            }
            
            assignRoleToUser(createdUser.getUserId(), teacherRole.getRoleId());
            
            // 5. 记录日志
            logActivity(adminId, "create_teacher", null, "超级管理员创建老师用户: " + username);
            
            return CommonResponse.success("老师用户创建成功", null);
            
        } catch (Exception e) {
            log.error("创建老师用户失败 - 用户名: {}, 错误信息: {}", username, e.getMessage(), e);
            return CommonResponse.fail(AuthResultCode.ERROR.code, "创建失败: " + e.getMessage());
        }
    }

    // 角色-权限分配
    @Override
    @Transactional
    public void assignPermissionToRole(Long roleId, Long permissionId) {
        RolePermission rolePermission = new RolePermission();
        rolePermission.setRoleId(roleId);
        rolePermission.setPermissionId(permissionId);
        rolePermissionMapper.insert(rolePermission);
        logActivity(null, "assign_permission", null, "分配权限: roleId=" + roleId + ", permissionId=" + permissionId);
    }

    @Override
    @Transactional
    public void removePermissionFromRole(Long roleId, Long permissionId) {
        rolePermissionMapper.delete(roleId, permissionId);
        logActivity(null, "remove_permission", null, "移除权限: roleId=" + roleId + ", permissionId=" + permissionId);
    }

    @Override
    public List<Permission> getRolePermissions(Long roleId) {
        return rolePermissionMapper.findPermissionsByRoleId(roleId);
    }

    @Override
    public boolean hasPermission(Long userId, String permissionName) {
        boolean hasPermission = userRoleMapper.hasPermission(userId, permissionName);
        logActivity(userId, "check_permission_" + permissionName, null, "权限检查: " + (hasPermission ? "通过" : "拒绝"));
        return hasPermission;
    }
    
    @Override
    public List<User> findUsersByRole(String roleName) {
        Role role = findRoleByName(roleName);
        if (role == null) {
            throw new RuntimeException("角色不存在: " + roleName);
        }
        return userRoleMapper.findUsersByRoleId(role.getRoleId());
    }
    
    @Override
    public List<User> findUsersByRoleId(Long roleId) {
        return userRoleMapper.findUsersByRoleId(roleId);
    }

    private void logActivity(Long userId, String action, Long examId, String details) {
        ActivityLog log = new ActivityLog();
        log.setUserId(userId);
        log.setAction(action);
        log.setExamId(examId);
        log.setCreatedAt(LocalDateTime.now());
        log.setDetails(details);
        activityLogMapper.insert(log);
    }
}
